
import UIKit
import CoreImage


extension UIImage {
    
    func resized(to size: CGSize, completion: @escaping (UIImage?) -> Void) {
        DispatchQueue.global(qos: .userInitiated).async {
            let renderer = UIGraphicsImageRenderer(size: size)
            let resizedImage = renderer.image { _ in
                self.draw(in: CGRect(origin: .zero, size: size))
            }
            DispatchQueue.main.async {
                completion(resizedImage)
            }
        }
    }
    
    func resizedWithAspectRatio(to maxSize: CGSize, completion: @escaping (UIImage?) -> Void) {
        DispatchQueue.global(qos: .userInitiated).async {
            let aspectRatio = min(maxSize.width / self.size.width, maxSize.height / self.size.height)
            let newSize = CGSize(width: self.size.width * aspectRatio, height: self.size.height * aspectRatio)
            let renderer = UIGraphicsImageRenderer(size: newSize)
            let resizedImage = renderer.image { _ in
                self.draw(in: CGRect(origin: .zero, size: newSize))
            }
            DispatchQueue.main.async {
                completion(resizedImage)
            }
        }
    }
    
    func resizedWithAspectRatio(to maxSize: CGSize) -> UIImage{
        let aspectRatio = min(maxSize.width / self.size.width, maxSize.height / self.size.height)
        let newSize = CGSize(width: self.size.width * aspectRatio, height: self.size.height * aspectRatio)
        let renderer = UIGraphicsImageRenderer(size: newSize)
        let resizedImage = renderer.image { _ in
            self.draw(in: CGRect(origin: .zero, size: newSize))
        }
        return resizedImage
    }
}
 

extension UIImage {
    /// 根据文件名初始化 UIImage，不使用缓存，根据屏幕 scale 自动匹配 @2x/@3x
    public convenience init?(fileName: String) {
        let scale = Int(UIScreen.main.scale)
        let possibleScales = scale == 3 ? [3, 2, 1] : [2, 3, 1]  // 优先当前 scale

        let name = (fileName as NSString).deletingPathExtension
        let ext = (fileName as NSString).pathExtension.isEmpty ? "png" : (fileName as NSString).pathExtension

        for s in possibleScales {
            let scaledName = "\(name)@\(s)x"
            if let path = Bundle.main.path(forResource: scaledName, ofType: ext) {
                if let image = UIImage(contentsOfFile: path) {
                    self.init(cgImage: image.cgImage!, scale: image.scale, orientation: image.imageOrientation)
                    return
                }
            }
        }

        // 尝试不带 @2x/@3x 的原图
        if let path = Bundle.main.path(forResource: name, ofType: ext),
           let image = UIImage(contentsOfFile: path) {
            self.init(cgImage: image.cgImage!, scale: image.scale, orientation: image.imageOrientation)
            return
        }

        return nil
    }
}

 
extension UIImage {

    /// 压缩图片：根据尺寸缩放 + JPEG 压缩（支持指定最大尺寸和最大文件大小）
    /// - Parameters:
    ///   - maxSizeKB: 最大大小，单位 KB（默认 1024KB）
    ///   - maxDimension: 图片最长边最大尺寸（默认 1280）
    /// - Returns: 压缩后的图片数据（JPEG 格式）
    func compressedImageData(maxSizeKB: Int = 1024, maxDimension: CGFloat = 1280) -> Data? {
        let maxSize = maxSizeKB * 1024
        var resizedImage = self

        // 如果尺寸过大，先等比缩放
        if max(size.width, size.height) > maxDimension {
            resizedImage = self.scaled(toMaxDimension: maxDimension)
        }

        // 使用二分查找压缩图片质量
        return resizedImage.compressToFitSize(maxSize)
    }

    /// 等比缩放图片（最长边为 maxDimension）
    private func scaled(toMaxDimension maxDimension: CGFloat) -> UIImage {
        let aspectRatio = size.width / size.height
        var newSize: CGSize

        if size.width > size.height {
            newSize = CGSize(width: maxDimension, height: maxDimension / aspectRatio)
        } else {
            newSize = CGSize(width: maxDimension * aspectRatio, height: maxDimension)
        }

        let format = UIGraphicsImageRendererFormat.default()
        format.scale = scale
        let renderer = UIGraphicsImageRenderer(size: newSize, format: format)

        return renderer.image { _ in
            draw(in: CGRect(origin: .zero, size: newSize))
        }
    }

    /// 压缩 JPEG 图片质量，使其小于 maxSize 字节（使用二分查找）
    private func compressToFitSize(_ maxSize: Int, minQuality: CGFloat = 0.4) -> Data? {
        var lower: CGFloat = minQuality
        var upper: CGFloat = 1.0
        var bestData: Data?

        while lower <= upper {
            let mid = (lower + upper) / 2
            guard let data = jpegData(compressionQuality: mid) else { break }

            if data.count > maxSize {
                upper = mid - 0.01
            } else {
                bestData = data
                lower = mid + 0.01
            }
        }

        return bestData
    }
}

extension UIImage {
    class func make(_ color: UIColor) -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1))
        return renderer.image { context in
            color.setFill()
            context.fill(CGRect(origin: .zero, size: CGSize(width: 1, height: 1)))
        }
    }
}


extension UIImage {

    static func generateQRCode(from string: String, size: CGFloat) -> UIImage? {
        guard let data = string.data(using: .utf8),
              let filter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
        
        filter.setValue(data, forKey: "inputMessage")
        filter.setValue("M", forKey: "inputCorrectionLevel") // L/M/Q/H 容错等级
        
        guard let ciImage = filter.outputImage else { return nil }
        
        let scale = UIScreen.main.scale
        let transform = CGAffineTransform(
            scaleX: (size * scale) / ciImage.extent.size.width,
            y: (size * scale) / ciImage.extent.size.height
        )
        let scaledImage = ciImage.transformed(by: transform)
        
        let context = CIContext()
        if let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) {
            return UIImage(cgImage: cgImage, scale: scale, orientation: .up)
        }
        return nil
    }
}

extension UIButton {
    func setBackgroundColor(_ color: UIColor, for state: UIControl.State) {
        let image = UIImage.make(color)
        self.setBackgroundImage(image, for: state)
    }
}
